<?php
/**
 * 采购单控制器
 */

namespace app\admin\controller;
use app\admin\traits\AdminSettingForm;
use app\admin\traits\SettingContent;
use app\common\model\Brand;
use app\common\model\Check;
use app\common\model\ComputeDetail;
use app\common\model\Dose;
use app\common\model\Meal;
use app\common\model\Menu;
use app\common\model\Offer;
use app\common\model\OfferDetail;
use app\common\model\ProjectLog;
use app\common\model\School;
use app\common\model\Send;
use app\common\model\Spec;
use app\common\model\Type;
use app\common\model\User;
use app\common\validate\SendValidate;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\db\Query;
use think\facade\Config;
use think\Request;
use think\response\Json;

class SendController extends AdminBaseController {
	use AdminSettingForm;
	use SettingContent;
	/**
	 * 列表
	 * @param Request $request
	 * @param Send $model
	 * @return string
	 * @throws Exception
	 */

	public function index(Request $request, Send $model): string {
		$param = $request->param();
		$data = $model->with(['school', 'user'])->scope('where', $param)
			->paginate([
				'list_rows' => $this->admin['admin_list_rows'],
				'var_page' => 'page',
				'query' => $request->get(),
			]);
		// 关键词，排序等赋值
		$this->assign($request->get());

		$this->assign([
			'data' => $data,
			'page' => $data->render(),
			'total' => $data->total(),
			'school_list' => School::select(),
			'user_list' => User::select(),

		]);
		return $this->fetch();
	}

	/**
	 * 添加
	 * @param Request $request
	 * @param Send $model
	 * @param SendValidate $validate
	 * @return string|Json
	 * @throws Exception
	 */
	public function add(Request $request, Send $model, SendValidate $validate) {
		if ($request->isPost()) {
			$param = $request->param();
			try {
				$param['detail'] = $this->getSendDetail($param);
			} catch (RuntimeException $exception) {
				return admin_error($exception->getMessage());
			}
			$validate_result = $validate->scene('admin_add')->check($param);
			if (!$validate_result) {
				return admin_error($validate->getError());
			}

			$param['money'] = array_sum(array_column($param['detail'], 'money'));
			$result = $model::create($param);
			$offer_details = $this->getOfferDetailAdd($param);
			$offer_detail_data = [
				'name' => $param['send_time'] . '报价单',
				'send_id' => $result->id,
				'code' => date('YmdHis') . rand(00000, 99999),
				'money' => array_sum(array_column($offer_details, 'money')),
				'detail' => $offer_details,
				'send_time' => $param['send_time'],
				'school_id' => $param['school_id'],
			];
			$offer_detail = OfferDetail::create($offer_detail_data);
			$url = URL_BACK;
			if (isset($param['_create']) && (int) $param['_create'] === 1) {
				$url = URL_RELOAD;
			}
			return $result ? admin_success('添加成功', [], $url) : admin_error();
		}
		$this->assign([
			'school_list' => School::select(),
			'user_list' => User::select(),
			'type_list' => Type::where('parent_id', '<>', 0)->select(),
			'spec_list' => Spec::select(),
			'brand_list' => Brand::select(),
			'user_list' => User::select(),
			'status_list' => Send::STATUS_LIST,
		]);

		return $this->fetch();
	}
	/**
	 * 修改
	 * @param $id
	 * @param Request $request
	 * @param Send $model
	 * @param SendValidate $validate
	 * @return string|Json
	 * @throws Exception
	 */
	public function edit($id, Request $request, Send $model, SendValidate $validate) {
		$data = $model->findOrEmpty($id);
		if ($request->isPost()) {
			$param = $request->param();
			try {
				$param['detail'] = $this->getSendDetail($param);
			} catch (RuntimeException $exception) {
				return admin_error($exception->getMessage());
			}
			$check = $validate->scene('admin_edit')->check($param);
			if (!$check) {
				return admin_error($validate->getError());
			}

			$offer = OfferDetail::where('send_id', $data['id'])->findOrEmpty();
			if (!$offer->isEmpty()) {
				$offer_detail = $offer['detail'];
				foreach ($offer['detail'] as $key => $Value) {

					$offer_detail[$key]['type_id'] = $param['detail'][$key]['type_id'];
					$offer_detail[$key]['spec_id'] = $param['detail'][$key]['spec_id'];
					$offer_detail[$key]['brand_id'] = $param['detail'][$key]['brand_id'];
					$offer_detail[$key]['num'] = $param['detail'][$key]['num'];
					$offer_detail[$key]['money'] = round($offer_detail[$key]['num'] * $offer_detail[$key]['price'], 2);
				}
				$offer_money = array_sum(array_column($offer_detail, 'money'));
				$offer->save(['detail' => $offer_detail, 'money' => $offer_money]);

				$offer_detail_list = OfferDetail::where('offer_id', $offer['offer_id'])->select()->toArray();
				$filter_detail = array_column($offer_detail_list, 'detail');
				$twoDimArray = [];

				// 遍历三维数组，将其转换为二维数组
				foreach ($filter_detail as $subArray) {
					foreach ($subArray as $item) {
						$twoDimArray[] = $item;
					}
				}

				$filter_detail = $this->array_do($twoDimArray);

				$offer_data = [
					'money' => array_sum(array_column($offer_detail_list, 'money')),
					'detail' => $filter_detail,
				];
				$offer = Offer::where('id', $offer['offer_id'])->update($offer_data);
			}
			$param['money'] = array_sum(array_column($param['detail'], 'money'));
			$result = $data->save($param);

			return $result ? admin_success('修改成功', [], URL_BACK) : admin_error('修改失败');
		}

		$this->assign([
			'data' => $data,
			'school_list' => School::select(),
			'user_list' => User::select(),
			'type_list' => Type::where('parent_id', '<>', 0)->select(),
			'spec_list' => Spec::select(),
			'brand_list' => Brand::select(),
			'user_list' => User::select(),
			'status_list' => Send::STATUS_LIST,
		]);

		return $this->fetch('add');
	}
	public function ceshi() {
		$this->add2(1);
	}
	public function add2($project_log_id) {

		$config = Config::get('site.site');

		$project_log = ProjectLog::where('id', $project_log_id)->findOrEmpty();
		if (!$project_log->isEmpty()) {
			$detail = [];
			$offer = [];
			//$dose_id_list = [];
			foreach ($project_log['detail'] as $key => $value) {

				$compute_detail_list = ComputeDetail::where('compute_id', $value['compute_id'])->select()->toArray();
				$dose_id_list = array_column($compute_detail_list, 'dose_id');
				//foreach ($compute_detail_list as $ck => $cv) {
				// 	$type_id_list = ['1281', '555', '1073', '557'];
				// 	$type = Type::where('name', $value['name'])->find();
				// 	if (in_array($type['id'], $type_id_list)) {
				// 		$school_id = 0;
				// 	} else {
				// 		$school_id = $cv['school_id'];
				// 	}
				// 	$dose = Dose::where('id', $cv['dose_id'])->find();
				// foreach ($dose['detail'] as $detail_key => $detail_value) {
				// 	$meal = Meal::where('id', $detail_value['meal_id'])->find();
				// 	foreach ($meal['detail'] as $mk => $mv) {
				// 		$menu = Menu::where('id', $mv['menu_id'])->find();
				// 		foreach ($menu['detail'] as $mmk => $mmv) {
				// 			$type = Type::where('id', $mmv['type_id'])->find();
				// 		}
				// 	}
				// }

				// 	$meal_id_list = array_column($dose['detail'], 'meal_id');
				// 	$meal_list = Meal::whereIn('id', $meal_id_list)->column('detail');
				// 	foreach ($meal_list as $mk => $mv) {
				// 		$meal_list[$mk] = array_column(json_decode($mv, true),'menu_id');
				// 	}
				// 	$menu_id_list = array_reduce($meal_list, 'array_merge', []);

				// 	$menu_list = Menu::whereIn('id',$menu_id_list)->column('detail');
				//     foreach ($menu_list as $mk => $mv) {
				// 		$menu_list[$mk] = array_column(json_decode($mv, true),'type_id');
				// 	}
				// 	$type_id_list = array_reduce($menu_list, 'array_merge', []);

				//exit();
				// foreach ($dose_value['detail2'] as $detail2_key => $detail2_value) {

				// 	$type_list[] = [
				// 		'type_id' => $detail2_value['type_id'],
				// 		'spec_id' => $detail2_value['spec_id'],
				// 		'brand_id' => $detail2_value['brand_id'],
				// 		'num' => $detail2_value['num'],
				// 		'school_id' => $order_value['school_id'],
				// 		'order_id' => $order_value['id'],
				// 		'dose_id' => $dose_value['id'],
				// 	];
				// }
				$detail[] = [
					'type_id' => Type::where('name', $value['name'])->where('tag', 1)->value('id'),
					'spec_id' => Spec::where('name', $value['spec'])->value('id'),
					'brand_id' => Brand::where('name', $value['brand'])->value('id'),

					'price' => $value['money'],
					'shou_num' => 0,
					'wei_num' => 0,
					'avg_price' => 0,

					'status' => 0,
					'beizhu' => '',
					//'school_id' => $school_id,

				];
				$price = round($value['money'] + ($value['money'] * ($config['price'] / 100)), 2);
				$offer[] = [
					'type_id' => Type::where('name', $value['name'])->where('tag', 1)->value('id'),
					'spec_id' => Spec::where('name', $value['spec'])->value('id'),
					'brand_id' => Brand::where('name', $value['brand'])->value('id'),

					'price' => $price,

					'status' => 0,
					//'school_id' => $school_id,

				];

				//}

			}

			$dose_list = Dose::whereIn('id', $dose_id_list)->select()->toArray();
			$offer_detail_id = [];
			$school_id = [];
			foreach ($dose_list as $dose_key => $dose_value) {

				$meal_list = [];
				$type_list = [];
				foreach ($dose_value['detail'] as $detail_key => $detail_value) {

					$meal_list[] = [
						'meal_id' => $detail_value['meal_id'],
						'num' => $detail_value['num'],
						'dose_id' => $dose_value['id'],
						'tag' => $dose_value['tag'],
					];
				}

				foreach ($dose_value['detail2'] as $detail2_key => $detail2_value) {

					$type_list[] = [
						'type_id' => $detail2_value['type_id'],
						'spec_id' => $detail2_value['spec_id'],
						'brand_id' => $detail2_value['brand_id'],
						'num' => $detail2_value['num'],

						'dose_id' => $dose_value['id'],
					];
				}
				foreach ($meal_list as $meal_key => $meal_value) {

					$meal = Meal::where('id', $meal_value['meal_id'])->findOrEmpty();
					if (!$meal->isEmpty()) {
						foreach ($meal['detail'] as $meal_detail_key => $meal_detail_value) {
							$menu_list[] = $meal_detail_value['menu_id'];
							$menu = Menu::where('id', $meal_detail_value['menu_id'])->findOrEmpty();
							if (!$menu->isEmpty()) {
								foreach ($menu['detail'] as $menu_detail_key => $menu_detail_value) {
									if ($meal_value['num'] == '') {
										$meal_value['num'] = 0;
									}
									if ($meal_value['tag'] == 1) {
										$meal_value['num'] = 1;
									}
									if ($menu_detail_value['num'] == '') {
										$menu_detail_value['num'] = 0;
									}
									$type_list[] = [
										'type_id' => $menu_detail_value['type_id'],
										'num' => $meal_value['num'] * $menu_detail_value['num'],
										'spec_id' => $menu_detail_value['spec_id'],
										'brand_id' => $menu_detail_value['brand_id'],

										'dose_id' => $meal_value['dose_id'],
									];
								}
							}
						}
					}
				}

				$send_detail = $this->array_do3($detail, $type_list);
				foreach ($send_detail as $dk => $dv) {
					$send_detail[$dk]['money'] = round($dv['price'] * $dv['num'], 2);
				}
				$send_detail = $this->array_do($send_detail);

				$offer_details = $this->array_do3($offer, $type_list);
				foreach ($offer_details as $ok => $ov) {
					$offer_details[$ok]['money'] = round($ov['price'] * $ov['num'], 2);
				}
				$offer_details = $this->array_do($offer_details);

				// foreach($type_list as $tk =>$tv){
				//     $type_list[$tk]['']
				// }
				$send_data = [
					'user_id' => $project_log['user_id'],
					'detail' => $send_detail,
					'code' => date('YmdHis') . rand(00000, 99999),
					'send_time' => $dose_value['week'],
					'school_id' => $dose_value['school_id'],
				];

				$result = Send::create($send_data);

				$offer_detail_data = [
					'name' => $dose_value['week'] . '报价单',
					'money' => array_sum(array_column($offer_details, 'money')),
					'detail' => $offer_details,
					'school_id' => $dose_value['school_id'],
				];
				$offer_detail = OfferDetail::create($offer_detail_data);
				$offer_detail_id[] = $offer_detail->id;
				$school_id[] = $dose_value['school_id'];

			}
			$school_id = array_unique($school_id);
			foreach ($school_id as $sk => $sv) {
				$offer_detail_list = OfferDetail::whereIn('id', $offer_detail_id)->where('school_id', $sv)->select()->toArray();
				$filter_detail = array_column($offer_detail_list, 'detail');
				$twoDimArray = [];

				// 遍历三维数组，将其转换为二维数组
				foreach ($filter_detail as $subArray) {
					foreach ($subArray as $item) {
						$twoDimArray[] = $item;
					}
				}

				$filter_detail = $this->array_do($twoDimArray);

				$start = date('Y-m-d', strtotime('next monday'));
				$end = date('Y-m-d', strtotime($start . '+ 6 days'));
				$offer_data = [
					'name' => $start . '-' . $end . '报价单',
					'money' => array_sum(array_column($filter_detail, 'money')),
					'detail' => $filter_detail,
					'school_id' => $sv,
				];
				$offer = Offer::create($offer_data);
				$offer_detail_id_list = array_column($offer_detail_list, 'id');
				OfferDetail::whereIn('id', $offer_detail_id_list)->update(['offer_id' => $offer->id]);
			}
		}

	}
	public function array_do3($array1, $array2) {
		$mergedArray = [];

		// Create a map for the first array using type_id as key
		$array1Map = [];
		foreach ($array1 as $item) {
			$typeId = $item['type_id'];
			$array1Map[$typeId] = $item;
		}

		// Merge arrays based on type_id and only keep the merged ones
		foreach ($array2 as $item) {
			$typeId = $item['type_id'];
			if (isset($array1Map[$typeId])) {
				$mergedArray[] = array_merge($array1Map[$typeId], $item);
			}
		}

		return $mergedArray;
	}
	public function array_do($array) {
		$result = [];

		foreach ($array as $item) {
			$type_id = $item['type_id'];
			if (!isset($result[$type_id])) {
				$result[$type_id] = $item;
			} else {
				$result[$type_id]['num'] += $item['num'];
				$result[$type_id]['money'] += $item['money'];
			}
		}

		$result = array_values($result);
		return $result;
	}
	public function array_do2($data) {
		$groupedData = [];

		foreach ($data as $item) {
			$school_id = $item['school_id'];
			$type_id = $item['type_id'];
			$key = $school_id . '-' . $type_id;

			if (!isset($groupedData[$key])) {
				$groupedData[$key] = $item;
			}

			$groupedData[$key]['num'] += $item['num'];
		}
		$result = array_values($groupedData);
		return $result;
	}
	function filterBySchoolId($array, $school_id) {
		return array_filter($array, function ($item) use ($school_id) {
			return $item['school_id'] == $school_id;
		});
	}

	/**
	 * 删除
	 * @param mixed $id
	 * @param Send $model
	 * @return Json
	 */
	public function del($id, Send $model): Json {
		$check = $model->inNoDeletionIds($id);
		if (false !== $check) {
			return admin_error('ID为' . $check . '的数据不能被删除');
		}

		$result = $model::destroy(static function ($query) use ($id) {
			/** @var Query $query */
			$query->whereIn('id', $id);
		});

		return $result ? admin_success('删除成功', [], URL_RELOAD) : admin_error('删除失败');
	}
	public function export(Request $request, Send $model): void {
		$param = $request->param();
		$data = $model->with(['school', 'user'])->where('id', $param['id'])->find();

		$head = ['商品名称', '单位', '待采购量', '采购价格', '备注', '商品状态', '客户下单明细', '商品条码', '商品编码'];
		$status = [
			'0' => '待采购',
			'1' => '已采购',
			'2' => '待送货',
			'3' => '已送货',
		];
		$body = [];
		foreach ($data['detail'] as $item) {
			$type = Type::where('id', $item['type_id'])->find();
			$spec = Spec::where('id', $item['spec_id'])->find();
			$brand = Brand::where('id', $item['brand_id'])->find();
			$record = [];
			$record['name'] = $type['name'];
			$record['brand'] = $brand['name'];
			$record['num'] = $item['num'];
			$record['price'] = $item['price'];
			$record['beizhu'] = ' ';
			$record['status'] = $status[$item['status']];
			$record['mx'] = '';
			$record['tm'] = '';
			$record['bm'] = '';

			$body[] = $record;
		}
		try {
			$spreadsheet = new Spreadsheet();
			$sheet = $spreadsheet->setActiveSheetIndex(0);

			$sheet->mergeCells("A1:H1"); //合并单元格
			$sheet->mergeCells("B2:C2"); //合并单元格
			$sheet->mergeCells("E2:F2"); //合并单元格
			$sheet->mergeCells("B3:C3"); //合并单元格
			$sheet->mergeCells("E3:F3"); //合并单元格
			$sheet->setCellValue("A1", "送货单(" . $data->user->nickname . ")")->getStyle('A1')->getFont()->setBold(true);
			$sheet->setCellValue("A2", "单据编号")->getStyle('A2')->getFont()->setBold(true);
			$sheet->setCellValue("B2", $data->code . ' ')->getStyle('B2')->getFont()->setBold(true);
			$sheet->setCellValue("D2", "发货日期")->getStyle('D2')->getFont()->setBold(true);
			$sheet->setCellValue("E2", $data->send_time)->getStyle('E2')->getFont()->setBold(true);
			$sheet->setCellValue("G2", "单据金额")->getStyle('G2')->getFont()->setBold(true);
			$sheet->setCellValue("H2", $data->money)->getStyle('H2')->getFont()->setBold(true);
			$sheet->setCellValue("A3", "创建时间")->getStyle('A3')->getFont()->setBold(true);
			$sheet->setCellValue("B3", $data->create_time)->getStyle('B3')->getFont()->setBold(true);
			$sheet->setCellValue("D3", "单据备注")->getStyle('D3')->getFont()->setBold(true);
			$sheet->setCellValue("G3", "单据状态")->getStyle('G3')->getFont()->setBold(true);
			$sheet->setCellValue("H3", $data->status_text)->getStyle('H3')->getFont()->setBold(true);
			$char_index = range('A', 'Z');
			$name = '采购单数据-' . date('YmdHis');
			// 处理超过26列
			$a = 'A';
			foreach ($char_index as $item) {
				$char_index[] = $a . $item;
			}

			// Excel 表格头
			foreach ($head as $key => $val) {
				$sheet->setCellValue($char_index[$key] . '5', $val);
			}

			// Excel body 部分
			foreach ($body as $key => $val) {
				$row = $key + 6;
				$col = 0;
				foreach ($val as $v) {
					$sheet->setCellValue($char_index[$col] . $row, $v);
					$col++;
				}
			}

			$spreadsheet->getActiveSheet()->setTitle('采购单');

			header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
			header('Content-Disposition: attachment;filename="' . $name . '.xlsx"');
			header('Cache-Control: max-age=0');

			$objWriter = IOFactory::createWriter($spreadsheet, 'Xlsx');
			$objWriter->save('php://output');
			exit();
		} catch (Exception $e) {
			exit($e->getMessage() . '(' . $e->getFile() . '-' . $e->getLine() . ')');
		}
	}

}
